/**
 * @var isAndroid 判断当前UA是否为安卓
 * @var isIOS 判断当前UA是否为iOS
 */
const u = navigator.userAgent;
export const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; // android终端
export const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); // ios终端
export const isWeiXin = !!/MicroMessenger/i.test(u); // 微信端

export const getWindow = () => {
    return window.__POWERED_BY_WUJIE__ ? window.parent : window;
};

export const getDocument = () => {
    return window.__POWERED_BY_WUJIE__ ? window.parent.document : window.document;
};

/**
 * @author: 邓子强
 * @Date: 2020/5/12
 * @function thousandBitSeparator 分隔千分位
 * @param num 数字
 * @param char 分隔符:默认为,
 * @param dealDecimal 分是否处理小数点后的数，默认为false
 */
export const thousandBitSeparator = (num, char = ',', dealDecimal = false) => {
    const [int = '0', decimal = ''] = num.toString().split('.');
    const turnInteger = int.replace(/(\d)(?=(\d{3})+$)/g, ($1) => $1 + char); // 被转换的整数
    if (dealDecimal && decimal) {
        const turnDecimal = decimal.replace(/(\d)(?=(\d{3})+$)/g, ($1) => $1 + char); // 被转换的整数
        return `${turnInteger}.${turnDecimal}`;
    }
    return decimal ? `${turnInteger}.${decimal}` : turnInteger;
};

/**
 * @function paddingZero 在尾部填充0
 * @author: 邓子强
 * @Date: 2020/8/27
 * @param num 数字或字符串
 * @param length 需要返回的长度
 */
export const paddingZero = (num, length) => {
    return `${'0'.repeat(length)}${num}`.slice(-length);
};

/**
 * @function copyContentH5
 * @description h5复制文本到剪切板
 * @author: 邓子强
 * @Date: 2022/5/20
 * @param content 欲复制的文本
 */
export const copyContentH5 = (content) => {
    const copyDom = document.createElement('div');
    copyDom.innerText = content;
    copyDom.style.position = 'absolute';
    copyDom.style.top = '0px';
    copyDom.style.right = '-9999px';
    document.body.appendChild(copyDom);
    // 创建选中范围
    const range = document.createRange();
    range.selectNode(copyDom);
    // 移除剪切板中内容
    window.getSelection().removeAllRanges();
    // 添加新的内容到剪切板
    window.getSelection().addRange(range);
    // 复制
    const successful = document.execCommand('copy');
    copyDom.parentNode.removeChild(copyDom);
    return successful;
};

/**
 * @function sleep
 * @description 休眠
 * @author: 邓子强
 * @Date: 2022/5/24
 * @param ms 毫秒
 */
export const sleep = (ms) => {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
};

/**
 * @function openImgPicker
 * @description 打开本地文件
 * @description showOpenFilePicker 仅PC端 chrome/Edge 86+, Opera 72+支持
 * @return {Array} fileList
 */
export const openImgPicker = async (multiple = true) => {
    if (window.showOpenFilePicker) {
        // 打开文件
        try {
            const files = await window.showOpenFilePicker({
                types: [
                    {
                        description: 'Images',
                        accept: {
                            'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp'],
                        },
                    },
                ],
                multiple,
            });
            // eslint-disable-next-line no-return-await
            return reformatHandleImgFiles(files);
        } catch (e) {
            return [];
        }
    }
    return [];
};
export const reformatHandleImgFiles = async (files) => {
    /* eslint no-restricted-syntax:off, no-await-in-loop:off */
    // 遍历选择的文件
    const fileList = [];
    for (const fileHandle of files) {
        // 获取文件内容
        const File = await fileHandle.getFile();
        // 读文件数据
        const buffer = await File.arrayBuffer();
        // 转成Blob url地址
        const src = URL.createObjectURL(new Blob([buffer]));
        const img = new Image();
        img.src = src;
        img.onload = () => {
            const { 1: fn, 2: ext } = /(.*)\.(.*)/g.exec(File.name);
            fileList.push({
                lastModified: File.lastModified,
                naturalName: File.name,
                name: `${fn}_size#${img.naturalWidth}x${img.naturalHeight}_space#${File.size}.${ext}`,
                ext,
                size: File.size,
                type: File.type,
                blobUrl: src,
                width: img.naturalWidth,
                height: img.naturalHeight,
                buffer,
            });
        };
    }
    return fileList;
};

// 获取assets静态资源
export const getAssetsFile = (url = '') => {
    return new URL(`../assets/images/${url}`, import.meta.url).href;
};

/**
 * @function 进度条
 * @auto 李博
 * @create: 2022/5/1
 * @param {number} initialNum 当前值
 * @param {number} totalNum  目标值
 */
export const percentageCalculation = (initialNum = 0, totalNum = 0) => {
    let iProc;
    if (!initialNum) {
        return 0;
    }
    (initialNum >= totalNum && (iProc = 100)) || (iProc = initialNum / (totalNum / 100));
    iProc > 100 && (iProc = 100);
    return iProc;
};
/**
 * @function 向上取整-进度条
 * @create: 2022/5/1
 * @param {number} initialNum 当前值
 * @param {number} totalNum  目标值
 */
export const percentageCalculationCeil = (initialNum = 0, totalNum = 0) => {
    let iProc;
    if (+initialNum === 0 && +totalNum === 0) {
        return 50;
    }
    if (!initialNum || +initialNum === 0) {
        return 0;
    }
    (initialNum >= totalNum && (iProc = 100)) ||
        (initialNum >= totalNum - initialNum && (iProc = initialNum / (totalNum / 100))) ||
        (iProc = Math.ceil(initialNum / (totalNum / 100)));
    iProc > 100 && (iProc = 100);
    return iProc;
};

/**
 * @description 将字符串数据递归反序列化成对象
 * @function JsonParseRecursion 递归解析为对象
 * @param {object,string} dataStr 需要反序列的数据
 * @return {object} {value,converted}
 */
export const JsonParseRecursion = (dataStr) => {
    if (typeof dataStr === 'string') {
        try {
            return JsonParseRecursion(JSON.parse(dataStr));
        } catch (e) {
            return {
                value: dataStr,
                converted: false,
            };
        }
    }
    if (dataStr instanceof Object) {
        Object.keys(dataStr).forEach((key) => {
            dataStr[key] = JsonParseRecursion(dataStr[key])['value'];
        });
        return {
            value: dataStr,
            converted: true,
        };
    }
    return {
        value: dataStr,
        converted: false,
    };
};

export const getBrowserLoggerConfig = () => {
    // 环境字段，取值为：prod、gray、pre、daily和local，其中：
    // prod表示线上环境。
    // gray表示灰度环境。
    // pre表示预发环境。
    // daily表示日常环境。
    // local表示本地环境。
    const getAlifeEnvironment = () => {
        const _env = process.env.NODE_ENV;
        if (
            window.location.origin.includes('127.0.0.1') ||
            window.location.origin.includes('localhost')
        ) {
            return 'local';
        }
        switch (_env) {
            case 'production':
                return 'prod';
            case 'pre':
                return 'pre';
            case 'test':
                return 'daily';
            case 'development':
                return 'daily';
            default:
                return 'local';
        }
    };

    const query = queryStringParse(window.location.search);

    return {
        pid: 'dktgsax37p@7cc099db239311f',
        appType: 'web',
        imgUrl: 'https://arms-retcode-sg.aliyuncs.com/r.png?',
        sendResource: true,
        enableLinkTrace: true,
        behavior: true,
        enableSPA: true,
        useFmp: true,
        environment: getAlifeEnvironment(),
        c1: query['client-language'] || null,
        c2: query.token || null,
    };
};

// ---------- 获取url参数相关方法 -----------
function validateArrayFormatSeparator(value) {
    if (typeof value !== 'string' || value.length !== 1) {
        throw new TypeError('arrayFormatSeparator must be single character string');
    }
}

function parseValue(value, options) {
    if (
        options.parseNumbers &&
        !Number.isNaN(Number(value)) &&
        typeof value === 'string' &&
        value.trim() !== ''
    ) {
        // eslint-disable-next-line no-param-reassign
        value = Number(value);
    } else if (
        options.parseBooleans &&
        value !== null &&
        (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')
    ) {
        // eslint-disable-next-line no-param-reassign
        value = value.toLowerCase() === 'true';
    }
    return value;
}

function keysSorter(input) {
    if (Array.isArray(input)) {
        return input.sort();
    }
    if (typeof input === 'object') {
        return keysSorter(Object.keys(input))
            .sort((a, b) => Number(a) - Number(b))
            .map((key) => input[key]);
    }
    return input;
}

function splitOnFirst(string, separator) {
    if (!(typeof string === 'string' && typeof separator === 'string')) {
        throw new TypeError('Expected the arguments to be of type `string`');
    }
    if (string === '' || separator === '') {
        return [];
    }
    const separatorIndex = string.indexOf(separator);
    if (separatorIndex === -1) {
        return [];
    }
    return [string.slice(0, separatorIndex), string.slice(separatorIndex + separator.length)];
}

function parserForArrayFormat(options) {
    switch (options.arrayFormat) {
        default: {
            return (key, value, accumulator) => {
                if (accumulator[key] === undefined) {
                    accumulator[key] = value;
                    return;
                }
                accumulator[key] = [...[accumulator[key]].flat(), value];
            };
        }
    }
}

const singleMatcherToken = '%[a-f0-9]{2}';
const singleMatcher = new RegExp(`(${singleMatcherToken})|([^%]+?)`, 'gi');

function decodeComponents(components, split) {
    try {
        // Try to decode the entire string first
        return [decodeURIComponent(components.join(''))];
    } catch {
        // Do nothing
    }
    if (components.length === 1) {
        return components;
    }
    // eslint-disable-next-line no-param-reassign
    split = split || 1;
    // Split the array in 2 parts
    const left = components.slice(0, split);
    const right = components.slice(split);
    return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));
}

function queryStringDecode(input, options) {
    if (options.decode) {
        try {
            return decodeURIComponent(input);
        } catch {
            let tokens = input.match(singleMatcher) || [];
            for (let i = 1; i < tokens.length; i++) {
                // eslint-disable-next-line no-param-reassign
                input = decodeComponents(tokens, i).join('');
                tokens = input.match(singleMatcher) || [];
            }
            return input;
        }
    }
    return input;
}

export function queryStringParse(query) {
    const options = {
        decode: true,
        sort: true,
        arrayFormat: 'none',
        arrayFormatSeparator: ',',
        parseNumbers: false,
        parseBooleans: false,
    };
    validateArrayFormatSeparator(options.arrayFormatSeparator);
    const formatter = parserForArrayFormat(options);
    // Create an object with no prototype
    const returnValue = Object.create(null);
    if (typeof query !== 'string') {
        return returnValue;
    }
    // eslint-disable-next-line no-param-reassign
    query = query.trim().replace(/^[?#&]/, '');
    if (!query) {
        return returnValue;
    }
    for (const [key, value] of Object.entries(returnValue)) {
        if (typeof value === 'object' && value !== null) {
            for (const [key2, value2] of Object.entries(value)) {
                value[key2] = parseValue(value2, options);
            }
        } else {
            returnValue[key] = parseValue(value, options);
        }
    }
    if (options.sort === false) {
        return returnValue;
    }
    for (const parameter of query.split('&')) {
        if (parameter === '') {
            // eslint-disable-next-line no-continue
            continue;
        }
        const parameter_ = options.decode ? parameter.replace(/\+/g, ' ') : parameter;
        let [key, value] = splitOnFirst(parameter_, '=');
        if (key === undefined) {
            key = parameter_;
        }
        // Missing `=` should be `null`:
        // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
        value =
            // eslint-disable-next-line no-nested-ternary
            value === undefined
                ? null
                : ['comma', 'separator', 'bracket-separator'].includes(options.arrayFormat)
                ? value
                : queryStringDecode(value, options);
        formatter(queryStringDecode(key, options), value, returnValue);
    }
    return (
        options.sort === true
            ? Object.keys(returnValue).sort()
            : Object.keys(returnValue).sort(options.sort)
    ).reduce((result, key) => {
        const value = returnValue[key];
        if (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) {
            // Sort object keys, not values
            // eslint-disable-next-line no-param-reassign
            result[key] = keysSorter(value);
        } else {
            // eslint-disable-next-line no-param-reassign
            result[key] = value;
        }
        return result;
    }, Object.create(null));
}
// ----------
